#include <LitStdAfx.h>
#include <LitMovableText.h>
#include <LitSceneManager.h>
#include <LitPhysicsWorld.h>
#include <LitRoot.h>

namespace Lit
{
	namespace Physics
	{
		Ogre::Overlay * DebugNodeText::g_pOverlay = NULL;

		DebugNodeText::DebugNodeText(const Ogre::MovableObject* p, const Ogre::Camera* c) {
			m_p = p;
			m_c = c;
			m_enabled = false;
			m_text = "";
 
			// create an overlay that we can use for later
			DebugNodeText::overlayInstance();
 
			char buf[15];
			sprintf_s<15>(buf, "c_%s", p->getName().c_str());
			m_elementName = buf;
			m_pContainer = static_cast<Ogre::OverlayContainer*>(Ogre::OverlayManager::getSingleton().createOverlayElement(
						"Panel", buf));
 
			DebugNodeText::overlayInstance()->add2D(m_pContainer);
 
			sprintf_s<15>(buf, "ct_%s", p->getName().c_str());
			m_elementTextName = buf;
			m_pText = Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", buf);
			assert(m_pText&&"Invalid ptr!");
			m_pText->setDimensions(1.0, 1.0);
			m_pText->setMetricsMode(Ogre::GMM_PIXELS);
			m_pText->setPosition(0, 0);
 
			m_pText->setParameter("font_name", "LucidaSans");
			m_pText->setParameter("char_height", "16");
			m_pText->setParameter("horz_align", "center");
			m_pText->setColour(Ogre::ColourValue(1.0, 1.0, 1.0));
 
			m_pContainer->addChild(m_pText);
			m_pContainer->setEnabled(false);

			enable(false);
		}
 
		DebugNodeText::~DebugNodeText() {
 
			// overlay cleanup -- Ogre would clean this up at app exit but if your app 
			// tends to create and delete these objects often it's a good idea to do it here.
 
			Ogre::OverlayManager *overlayManager = Ogre::OverlayManager::getSingletonPtr();
			m_pContainer->removeChild(m_elementTextName);
			DebugNodeText::overlayInstance()->remove2D(m_pContainer);
			overlayManager->destroyOverlayElement(m_pText);
			overlayManager->destroyOverlayElement(m_pContainer);
		}
		
		Ogre::Overlay* DebugNodeText::overlayInstance(){
			if(g_pOverlay == NULL)
			{
				g_pOverlay = Ogre::OverlayManager::getSingleton().create("floatingTextOverlay");
				g_pOverlay->show();
			}
			return g_pOverlay;
		}
		bool DebugNodeText::isEnabled() const{ return m_enabled; }
		void DebugNodeText::enable(bool enable) {
			m_enabled = enable;
			if (enable)
			{
				m_pContainer->show();
			}
			else
			{
				m_pContainer->hide();
			}
		}
 
		void DebugNodeText::update()  {
			if (!m_enabled)
				return;
 
			const Ogre::AxisAlignedBox& bbox = m_p->getWorldBoundingBox(true);
			Ogre::Matrix4 mat = m_c->getViewMatrix();
 
			bool behind = false;
 
			// We want to put the text point in the center of the top of the AABB Box.
			Ogre::Vector3 topcenter = bbox.getCenter();
			// Y is up.
			topcenter.y += bbox.getHalfSize().y;
			topcenter = mat * topcenter;
			// We are now in screen pixel coords and depth is +Z away from the viewer.
			behind = (topcenter.z > 0.0);
 
			if(behind)
			{
				// Don't show text for objects behind the camera.
				m_pContainer->setPosition(-1000, -1000);
			}
			else
			{
				// Not in pixel coordinates, in screen coordinates as described above.
				// We convert to screen relative coord by knowing the window size.
				// Top left screen corner is 0, 0 and the bottom right is 1,1
				// The 0.45's here offset alittle up and right for better "text above head" positioning.
				// The 2.2 and 1.7 compensate for some strangeness in Ogre projection?
				// Tested in wide screen and normal aspect ratio.
				m_pContainer->setPosition(0.45f - topcenter.x / (2.2f * topcenter.z), 
					topcenter.y / (1.7f * topcenter.z) + 0.45f);
				// Sizse is relative to screen size being 1.0 by 1.0 (not pixels size)
				m_pContainer->setDimensions(0.1f, 0.1f);
			}
		}
		void DebugNodeText::setText(const Ogre::String& text) {
			m_text = text;
			m_pText->setCaption(m_text);
		}
		const Ogre::String& DebugNodeText::getText() const{ return m_text; }

	};
};
